﻿/*******************************************************
 * 
 * 作者：胡庆访
 * 创建时间：20100408
 * 说明：命令UI生成
 * 运行环境：.NET 3.5 SP1
 * 版本号：1.0.0
 * 
 * 历史记录：
 * 创建文件 胡庆访 20100408
 * 
*******************************************************/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Avalon.Windows.Controls;
using AvalonDock;
using Csla;
using Itenso.Windows.Input;

using OpenExpressApp.MetaModel;
using OpenExpressApp.Module.Command;
using OpenExpressApp.Module.Library;
using OpenExpressApp.Module.Library.Security;
using OpenExpressApp.Module.WPF.Controls;
using OpenExpressApp.Module.WPF.Templete;
using OpenExpressApp.Types;
using OpenExpressApp.WPF.Command;
using OpenExpressApp.WPF.Controls;
using OpenExpressApp.WPF.Editors;
using Wpf.Controls;
namespace OpenExpressApp.Module.WPF
{
    internal class CommandUIGenerator
    {
        private IUIFactory _uiFactory;

        public CommandUIGenerator(IUIFactory uiFactory)
        {
            Debug.Assert(uiFactory != null, "uiFactory != null");

            this._uiFactory = uiFactory;
        }

        /// <summary>
        /// 添加弹出子窗体按钮
        /// </summary>
        /// <param name="toolBarItems"></param>
        /// <param name="boType"></param>
        public void CreatePopChildCommandsForToolBar(ItemCollection toolbarItems, Type boType, WPFObjectView view)
        {
            //添加弹出子表按钮。
            //var toolbarItems = childToolbar.Items;
            var showChildButton = ApplicationModel.Commands.First(c => (c.Id == CommandNames.ChildShowView));
            foreach (var item in ApplicationModel.GetBusinessObjectInfo(boType).BOsPropertyInfos)
            {
                if ((null != item.ChildShowTypeAttribute) &&
                    (item.ChildShowTypeAttribute.ChildShowType == ChildObjectShowType.Popup))
                {
                    CommandAdapter cmd = CommandRepository.NewCommand(showChildButton.Id) as CommandAdapter;
                    var btn = new Button();
                    btn.Content = item.ChildShowTypeAttribute.PopName;
                    btn.Name = "btn" + showChildButton.ProgramingName;
                    btn.CommandParameter = view;
                    ButtonCommand.SetCommand(btn, cmd);
                    toolbarItems.Add(btn);
                    var cumtomParams = cmd.CoreCommand.CustomParams;
                    cumtomParams.Add(CommandCustomParams.ChildViewName, item.BOType);
                }
            }
        }

        /// <summary>
        /// 为toolbar生成对应boType的commands
        /// </summary>
        /// <param name="toolbar">需要生成Commands的toolbar</param>
        /// <param name="boType">toolbar是为这个类型提供服务</param>
        /// <param name="view"></param>
        /// <param name="commands">在这个command集合中筛选</param>
        public void CreateCommandsForToolBar(ToolBar toolbar, Type boType, ObjectView view, BoInfoOperationList commands)
        {
            //Key: GroupName
            //Value: 需要在这个组中显示的控件集合
            var itemsInGroups = new Dictionary<string, List<FrameworkElement>>();
            var itemsInToolBar = new List<FrameworkElement>();
            var itemsInContextMenu = new List<FrameworkElement>();

            var boInfo = ApplicationModel.GetBusinessObjectInfo(boType);
            var toolbarCommands = toolbar.GetAttachedCommands();

            for (int i = 0, c = commands.Count; i < c; i++)
            {
                var command = commands[i].Operation.Command;

                #region 过滤掉不需要生成的Command

                //自动命令，不需要生成
                if (command.AutoExecuting) continue;

                //考虑权限
                var curIdentity = Csla.ApplicationContext.User.Identity as OEAIdentity;
                if (curIdentity.HavePermissionOnOperation(boInfo.Id, new Guid(command.Id)) == false) continue;

                //过滤相同的command
                if (toolbarCommands.Any(commandAdded => commandAdded.Id == command.Id)) continue;

                if (!command.CanVisible(view)) continue;

                #endregion

                //给这个toolbar附加这个命令
                toolbarCommands.Add(command);

                #region 生成使用的命令控件

                if (command.CommandType == CommandType.Menu)
                {
                    #region 使用MenuItem加入ContextMenu

                    MenuItem menuItem = new MenuItem();
                    menuItem.CommandParameter = view;
                    MenuItemCommand.SetCommand(menuItem, CommandRepository.NewCommand(command.Id));
                    itemsInContextMenu.Add(menuItem);

                    #endregion
                }
                else
                {
                    string group = command.Group;
                    //如果是加入到filter中command
                    if (string.IsNullOrEmpty(command.Group) == false)
                    {
                        #region 使用MenuItem加入到组中

                        FrameworkElement elementToAdd = null;

                        //使用MenuItem加入
                        MenuItem menuItem = new MenuItem();
                        menuItem.CommandParameter = view;
                        MenuItemCommand.SetCommand(menuItem, CommandRepository.NewCommand(command.Id));

                        //加入组中
                        List<FrameworkElement> menuItems = null;
                        if (itemsInGroups.TryGetValue(group, out menuItems) == false)
                        {
                            menuItems = new List<FrameworkElement>();
                            itemsInGroups[group] = menuItems;
                        }

                        #region 带参数的命令

                        CommandAdapter cmd = CommandRepository.NewCommand(command.Id) as CommandAdapter;
                        var parametrizedCommand = cmd.CoreCommand as IParametrizedCommand;
                        if (parametrizedCommand != null)
                        {
                            var panel = new DockPanel();

                            var control = parametrizedCommand.CreateControl();

                            panel.Children.Add(new Separator());
                            panel.Children.Add(control);
                            panel.Children.Add(menuItem);

                            elementToAdd = panel;
                        }
                        else
                        {
                            elementToAdd = menuItem;
                        }

                        #endregion

                        menuItems.Add(elementToAdd);

                        #endregion
                    }
                    else
                    {
                        FrameworkElement elementToAdd = null;

                        #region 带参数的命令

                        Panel panel = null;

                        var cmd = CommandRepository.NewCommand(command.Id) as CommandAdapter;
                        var parametrizedCommand = cmd.CoreCommand as IParametrizedCommand;
                        if (parametrizedCommand != null)
                        {
                            panel = new DockPanel();
                            var control = parametrizedCommand.CreateControl();

                            panel.Children.Add(new Separator());
                            panel.Children.Add(control);
                        }

                        #endregion

                        #region 使用Button加入

                        var btn = new Button();
                        btn.Name = "btn" + command.ProgramingName;
                        btn.CommandParameter = view;
                        ButtonCommand.SetCommand(btn, cmd);

                        if (panel != null)
                        {
                            panel.Children.Insert(0, btn);

                            Border border = new Border();
                            border.BorderThickness = new Thickness(1);
                            border.BorderBrush = new SolidColorBrush(Colors.Silver);
                            border.Child = panel;
                            elementToAdd = border;

                            elementToAdd = border;
                        }
                        else
                        {
                            elementToAdd = btn;
                        }

                        #endregion

                        itemsInToolBar.Add(elementToAdd);
                    }
                }

                #endregion
            }

            var toolbarItems = toolbar.Items;

            #region 加入Group

            if (itemsInGroups.Count > 0)
            {
                foreach (var groupControls in itemsInGroups)
                {
                    var groupName = groupControls.Key;
                    var controls = groupControls.Value;

                    //CommandCategory.Group类型下的命令需要在一个下拉列表中显示
                    SplitButton splitButton = new SplitButton()
                    {
                        VerticalAlignment = VerticalAlignment.Center,
                        HorizontalAlignment = HorizontalAlignment.Center,
                        Mode = SplitButtonMode.Dropdown,
                        Content = groupName,
                    };
                    foreach (var item in controls)
                    {
                        splitButton.Items.Add(item);
                    }
                    toolbarItems.Add(splitButton);
                }
            }

            #endregion

            #region 在Group之后，把其它控件加入ToolBar

            foreach (var item in itemsInToolBar)
            {
                toolbarItems.Add(item);
            }

            #endregion

            #region 加入ContextMenu

            if (itemsInContextMenu.Count > 0)
            {
                var mainContentControl = toolbar.GetServicedControl();
                if (mainContentControl != null)
                {
                    var contextMenu = new ContextMenu();
                    foreach (var menu in itemsInContextMenu)
                    {
                        contextMenu.Items.Add(menu);
                    }
                    mainContentControl.ContextMenu = contextMenu;
                }
            }

            #endregion

            if (toolbarItems.Count == 0)
            {
                toolbar.Visibility = Visibility.Collapsed;
            }
        }
    }
}
